package com.meterhuang.thread.foobar;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 可重入锁reentrant lock
 *
 * @author meterhuang
 * @date 2021/09/08 17:26
 */
public class FooBarReentrant {

	private int n;

	public FooBarReentrant(int n) {
		this.n = n;
	}

	private Lock lock = new ReentrantLock(true);

	private final Condition condition = lock.newCondition();

	private volatile boolean flag = true;

	public void foo(Runnable printFoo) throws InterruptedException {
		for (int i = 0; i < n; i++) {
			lock.lock();
			try {
				while (!flag) {
					condition.await();
				}
				printFoo.run();
				flag = false;
				condition.signal();
			} finally {
				lock.unlock();
			}
		}
	}

	public void bar(Runnable printBar) throws InterruptedException {
		for (int i = 0; i < n; ++i) {
			lock.lock();
			try {
				while(flag) {
					condition.await();
				}
				printBar.run();
				flag = true;
				condition.signal();
			} finally {
				lock.unlock();
			}
		}
	}

}
